# gozerbot/wait.py
#
#

""" wait for ircevent """

__copyright__ = 'this file is in the public domain'

from gozerbot.generic import rlog
import gozerbot.thr as thr
import time

class Wait(list):

    """ lists of ircevents to wait for """

    def __init__(self):
        list.__init__(self)
        self.ticket = 0

    def register(self, cmnd, catch, queue, timeout=15):
        """ register wait for cmnd """
        rlog(1, 'wait', 'registering for cmnd ' + cmnd)
        catch = catch.lower()
        self.ticket += 1
        self.append((cmnd, catch, queue, self.ticket))
        if timeout:
            # start timeout thread
            thr.start_new_thread(self.dotimeout, (timeout, self.ticket))
        return self.ticket

    def check(self, ievent):
        """ check if there are wait items for ievent """
        cmnd = ievent.cmnd
        for itemnr in range(len(self)-1, -1, -1):
            item = self[itemnr]
            doit = 0
            if item[0] == cmnd:
                if cmnd == 'PRIVMSG' and ievent.nick.lower() == item[1]:
                    doit = 1
                elif cmnd != 'PRIVMSG' and \
ievent.postfix.lower().find(item[1]) != -1:
                    doit = 1
                if doit:
                    ievent.ticket = item[3]
                    item[2].put_nowait(ievent)
                    try:
                        del self[itemnr]
                    except IndexError:
                        pass
                    rlog(1, 'wait', 'got response for %s' % item[0])

    def dotimeout(self, timeout, ticket):
        """ start timeout thread for wait with ticket nr """
        rlog(1, 'wait', 'starting timeouthread for %s' % str(ticket))
        time.sleep(float(timeout))
        self.delete(ticket)
  
    def delete(self, ticket):
        """ delete wait item with ticket nr """
        for itemnr in range(len(self)-1, -1, -1):
            item = self[itemnr]
            if item[3] == ticket:
                item[2].put_nowait(None)
                try:
                    del self[itemnr]
                    rlog(1, 'wait', 'deleted ' + str(ticket))
                except IndexError:
                    pass
                return 1

class Privwait(Wait):

    """ wait for privmsg """

    def register(self, catch, queue, timeout=15):
        """ register wait for privmsg """
        rlog(1, 'privwait', 'registering for ' + catch)
        catch = catch.lower()
        self.ticket += 1
        self.append((catch, queue, self.ticket))
        if timeout:
            thr.start_new_thread(self.dotimeout, (timeout, self.ticket))
        return self.ticket

    def check(self, ievent):
        """ check if there are wait items for ievent """
        for itemnr in range(len(self)-1, -1, -1):
            item = self[itemnr]
            if ievent.nick.lower() == item[0]:
                ievent.ticket = item[2]
                item[1].put_nowait(ievent)
                try:
                    del self[itemnr]
                except IndexError:
                    pass
                rlog(1, 'wait', 'got response for %s' % item[0])

    def delete(self, ticket):
        """ delete wait item with ticket nr """
        for itemnr in range(len(self)-1, -1, -1):
            item = self[itemnr]
            if item[2] == ticket:
                item[1].put_nowait(None)
                try:
                    del self[itemnr]
                    rlog(1, 'wait', 'deleted ' + str(ticket))
                except IndexError:
                    pass
                return 1

class Jabberwait(Wait):

    def register(self, catch, queue, timeout=15):
        """ register wait for privmsg """
        rlog(1, 'privwait', 'registering for ' + catch)
        catch = catch.lower()
        self.ticket += 1
        self.append((catch, queue, self.ticket))
        if timeout:
            thr.start_new_thread(self.dotimeout, (timeout, self.ticket))
        return self.ticket

    def check(self, msg):
        """ check if <msg> is waited for """
        for teller in range(len(self)-1,-1,-1):
            i = self[teller]
            if i[0] == msg.userhost:
                msg.ticket = i[2]
                i[1].put_nowait(msg)
                del self[teller]
                rlog(1,'wait','got response for %s' % i[0])
                return 1

    def delete(self, ticket):
        """ delete wait item with ticket nr """
        for itemnr in range(len(self)-1, -1, -1):
            item = self[itemnr]
            if item[2] == ticket:
                item[1].put_nowait(None)
                try:
                    del self[itemnr]
                    rlog(1, 'wait', 'deleted ' + str(ticket))
                except IndexError:
                    pass
                return 1
